---
title: Package System and Modularity
---

This module explores Go's package system and module management, which are fundamental to organizing and structuring Go code. Unlike JavaScript's module system, Go uses a unique approach to package management and dependency resolution.

## Understanding Go Packages

A **package** in Go is a way to group related code together. Every Go file belongs to a package, and packages are the primary mechanism for code organization and reuse.

### Package Declaration

Every Go file must start with a package declaration, which determines the package name.

#### Package Declaration Rules

In Go, **all `.go` files in the same folder must use the same `package` declaration**. This is one of the fundamental rules of Go.

<UniversalEditor title="Package Declaration Rules Comparison" compare={true}>
```javascript !! js
// JavaScript: Each file can have different module names
// file: middleware/auth.js
export function authMiddleware() {
    // Authentication middleware logic
}

// file: middleware/cors.js
export function corsMiddleware() {
    // CORS middleware logic
}

// file: middleware/logging.js
export function loggingMiddleware() {
    // Logging middleware logic
}

// Need to import separately when using
import { authMiddleware } from './middleware/auth.js';
import { corsMiddleware } from './middleware/cors.js';
import { loggingMiddleware } from './middleware/logging.js';
```

```go !! go
// Go: All files in the same folder use the same package name
// file: middleware/auth.go
package middleware

func AuthMiddleware() {
    // Authentication middleware logic
}

// file: middleware/cors.go
package middleware

func CorsMiddleware() {
    // CORS middleware logic
}

// file: middleware/logging.go
package middleware

func LoggingMiddleware() {
    // Logging middleware logic
}

// Only need to import the package once when using
import "my-project/middleware"

func main() {
    middleware.AuthMiddleware()
    middleware.CorsMiddleware()
    middleware.LoggingMiddleware()
}
```
</UniversalEditor>

#### Package Naming Conventions

<UniversalEditor title="Package Naming Conventions Comparison" compare={true}>
```javascript !! js
// JavaScript: Module system (ES6)
// file: math.js
export const PI = 3.14159;
export function add(a, b) {
    return a + b;
}
export function multiply(a, b) {
    return a * b;
}

// file: main.js
import { PI, add, multiply } from './math.js';
console.log(PI);
console.log(add(5, 3));
```

```go !! go
// Go: Package system
// file: math/math.go
package math

const PI = 3.14159

func Add(a, b int) int {
    return a + b
}

func Multiply(a, b int) int {
    return a * b
}

// file: main.go
package main

import (
    "fmt"
    "./math" // Import local package
)

func main() {
    fmt.Println(math.PI)
    fmt.Println(math.Add(5, 3))
    fmt.Println(math.Multiply(4, 6))
}
```
</UniversalEditor>

#### Real Project Example

Let's understand package declaration rules through a real project structure:

<UniversalEditor title="Real Project Structure Example" compare={true}>
```javascript !! js
// JavaScript: Project structure
my-project/
├── src/
│   ├── middleware/
│   │   ├── auth.js        // Independent module
│   │   ├── cors.js        // Independent module
│   │   └── logging.js     // Independent module
│   ├── utils/
│   │   ├── math.js        // Independent module
│   │   └── string.js      // Independent module
│   └── main.js
├── package.json
└── node_modules/

// Each file is an independent module
// file: middleware/auth.js
export function authMiddleware() {
    return "auth logic";
}

// file: middleware/cors.js
export function corsMiddleware() {
    return "cors logic";
}

// Need to import separately when using
import { authMiddleware } from './middleware/auth.js';
import { corsMiddleware } from './middleware/cors.js';
```

```go !! go
// Go: Project structure
my-project/
├── internal/
│   ├── middleware/
│   │   ├── auth.go        // package middleware
│   │   ├── cors.go        // package middleware
│   │   └── logging.go     // package middleware
│   └── utils/
│       ├── math.go        // package utils
│       └── string.go      // package utils
├── cmd/
│   └── main.go           // package main
├── go.mod
└── go.sum

// All files in the same folder use the same package name
// file: internal/middleware/auth.go
package middleware

func AuthMiddleware() string {
    return "auth logic"
}

// file: internal/middleware/cors.go
package middleware

func CorsMiddleware() string {
    return "cors logic"
}

// file: internal/middleware/logging.go
package middleware

func LoggingMiddleware() string {
    return "logging logic"
}

// Only need to import the package once when using
import "my-project/internal/middleware"

func main() {
    middleware.AuthMiddleware()
    middleware.CorsMiddleware()
    middleware.LoggingMiddleware()
}
```
</UniversalEditor>

#### Important Notes

1. **Package Name Consistency**: All `.go` files in the same folder must use the same `package` declaration
2. **Compilation Error**: If this rule is violated, the Go compiler will report an error
3. **Import Method**: When importing, only need to specify the package path, not specific files
4. **Naming Conventions**: Package names are usually lowercase, avoid underscores
5. **Package Name vs Folder Name**: Package names are usually the same as folder names, but not mandatory

## Go Modules vs JavaScript Package Managers

Go modules are the modern way to manage dependencies in Go, similar to npm/yarn in JavaScript, but with some key differences.

### Dependency Package Format Comparison

Go and JavaScript have fundamentally different approaches to dependency package formats:

<UniversalEditor title="Dependency Package Format Comparison" compare={true}>
```javascript !! js
// JavaScript: Package name format
// package.json
{
  "dependencies": {
    "express": "^4.18.2",           // Simple package name
    "@angular/core": "^16.0.0",     // Scoped package
    "lodash": "^4.17.21",           // Simple package name
    "@types/node": "^20.0.0"        // Type definition package
  }
}

// Install using package names
// npm install express
// npm install @angular/core
// npm install lodash

// Import using package names
import express from 'express';
import { Component } from '@angular/core';
import _ from 'lodash';
```

```go !! go
// Go: Module path format
// go.mod
module my-project

go 1.21

require (
    github.com/gin-gonic/gin v1.9.1        // Complete Git repository path
    github.com/go-sql-driver/mysql v1.7.1  // Database driver
    golang.org/x/text v0.14.0              // Official extension library
    google.golang.org/grpc v1.59.0         // Google official library
    k8s.io/client-go v0.28.0               // Kubernetes client
)

// Install using complete paths
// go get github.com/gin-gonic/gin
// go get golang.org/x/text
// go get google.golang.org/grpc

// Import using complete paths
import (
    "github.com/gin-gonic/gin"
    "golang.org/x/text/transform"
    "google.golang.org/grpc"
)
```
</UniversalEditor>

### Package Naming Convention Differences

<UniversalEditor title="Package Naming Convention Comparison" compare={true}>
```javascript !! js
// JavaScript: Flexible package naming
// 1. Simple package names
"express"
"lodash"
"axios"

// 2. Scoped packages (organizations/companies)
"@angular/core"
"@types/node"
"@babel/core"

// 3. Private packages (requires npm configuration)
"@mycompany/private-lib"

// 4. Local packages
"file:../local-package"
"file:./relative-path"

// 5. Git repositories (less commonly used)
"git+https://github.com/user/repo.git"
"git+ssh://git@github.com/user/repo.git#branch"

// Package names can be arbitrary, mainly depends on npm registry
```

```go !! go
// Go: Git repository-based module paths
// 1. GitHub repositories (most common)
"github.com/gin-gonic/gin"
"github.com/go-sql-driver/mysql"
"github.com/gorilla/mux"

// 2. Official extension libraries
"golang.org/x/text"
"golang.org/x/net"

// 3. Google official libraries
"google.golang.org/grpc"
"google.golang.org/protobuf"

// 4. Other Git hosting services
"gitlab.com/user/project"
"bitbucket.org/user/project"
"gitee.com/user/project"

// 5. Private repositories
"git.company.com/team/project"
"internal.company.com/private-lib"

// 6. Local modules (during development)
"my-project/internal/utils"
"my-project/pkg/math"

// Module paths must correspond to actual Git repository paths
```
</UniversalEditor>

### Dependency Resolution Mechanism Comparison

<UniversalEditor title="Dependency Resolution Mechanism Comparison" compare={true}>
```javascript !! js
// JavaScript: Registry-based resolution
// 1. Default resolution from npm registry
npm install express
// Resolves: https://registry.npmjs.org/express

// 2. Can configure different registries
npm config set registry https://registry.npm.taobao.org/

// 3. Private registries
npm install @mycompany/private-lib
// Resolves: https://npm.mycompany.com/@mycompany/private-lib

// 4. Scoped packages
npm install @angular/core
// Resolves: https://registry.npmjs.org/@angular/core

// 5. Version resolution
"express": "^4.18.2"  // Semantic versioning
"lodash": "~4.17.21"  // Patch version
"axios": "latest"     // Latest version

// 6. Dependency tree management
// node_modules/
// ├── express/
// │   ├── package.json
// │   └── node_modules/
// │       └── accepts/
// └── lodash/
```

```go !! go
// Go: Git repository-based resolution
// 1. Directly fetch from Git repositories
go get github.com/gin-gonic/gin
// Resolves: https://github.com/gin-gonic/gin.git

// 2. Support multiple Git protocols
// HTTPS: https://github.com/user/repo.git
// SSH: git@github.com:user/repo.git
// Git: git://github.com/user/repo.git

// 3. Private repository support
go get git.company.com/team/project
// Requires Git authentication configuration

// 4. Version resolution (based on Git tags)
"github.com/gin-gonic/gin v1.9.1"  // Specific version
"github.com/gin-gonic/gin latest"  // Latest version
"github.com/gin-gonic/gin master"  // Branch

// 5. Module caching
// $GOPATH/pkg/mod/
// ├── github.com/
// │   └── gin-gonic/
// │       └── gin@v1.9.1/

// 6. Proxy support (Go 1.13+)
// GOPROXY=https://proxy.golang.org,direct
// Or private proxy: GOPROXY=https://proxy.company.com,direct
```
</UniversalEditor>

### Module Initialization

<UniversalEditor title="Module Initialization Comparison" compare={true}>
```javascript !! js
// JavaScript: npm/yarn initialization
// package.json (created by npm init)
{
  "name": "my-project",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18.2",
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "jest": "^29.5.0"
  }
}

// Install dependencies
// npm install
// or
// yarn install
```

```go !! go
// Go: Module initialization
// go.mod (created by go mod init)
module my-project

go 1.21

require (
    github.com/gin-gonic/gin v1.9.1
    github.com/go-sql-driver/mysql v1.7.1
)

// Initialize module
// go mod init my-project

// Add dependencies
// go get github.com/gin-gonic/gin
// go get github.com/go-sql-driver/mysql
```
</UniversalEditor>

## Package Organization and Structure

Go has specific conventions for organizing packages and projects.

### Standard Project Layout

<UniversalEditor title="Project Structure Comparison" compare={true}>
```javascript !! js
// JavaScript: Typical project structure
my-project/
├── package.json
├── node_modules/
├── src/
│   ├── components/
│   │   ├── Header.js
│   │   └── Footer.js
│   ├── utils/
│   │   ├── math.js
│   │   └── helpers.js
│   └── main.js
├── tests/
│   └── test.js
└── README.md
```

```go !! go
// Go: Standard project structure
my-project/
├── go.mod
├── go.sum
├── cmd/
│   └── main.go
├── internal/
│   ├── handlers/
│   │   └── user.go
│   └── models/
│       └── user.go
├── pkg/
│   ├── math/
│   │   └── math.go
│   └── utils/
│       └── helpers.go
├── api/
│   └── routes.go
├── tests/
│   └── math_test.go
└── README.md
```
</UniversalEditor>

## Import System

Go's import system is more restrictive than JavaScript's, requiring explicit imports and following specific conventions.

### Import Types and Usage

<UniversalEditor title="Import System Comparison" compare={true}>
```javascript !! js
// JavaScript: Various import styles
// Default import
import express from 'express';

// Named imports
import { useState, useEffect } from 'react';

// Namespace import
import * as math from './math.js';

// Dynamic import
const module = await import('./dynamic-module.js');

// Destructuring with renaming
import { add as addNumbers } from './math.js';

// Default and named imports
import defaultExport, { namedExport } from './module.js';
```

```go !! go
// Go: Import system
package main

import (
    // Standard library imports
    "fmt"
    "net/http"
    "time"
    
    // Third-party imports
    "github.com/gin-gonic/gin"
    "github.com/go-sql-driver/mysql"
    
    // Local imports
    "./internal/handlers"
    "./pkg/math"
)

// Import with alias
import (
    mymath "./pkg/math"
)

// Import with dot (brings all names into current scope)
import (
    . "./pkg/math" // Now you can use Add() directly instead of math.Add()
)

// Import with underscore (for side effects only)
import (
    _ "github.com/go-sql-driver/mysql" // Register MySQL driver
)

func main() {
    fmt.Println("Hello, Go!")
    fmt.Println(math.Add(5, 3))
    fmt.Println(mymath.Multiply(4, 6))
}
```
</UniversalEditor>

## Package Visibility and Exports

Go uses capitalization to control visibility, unlike JavaScript's explicit export/import system.

<UniversalEditor title="Visibility Rules Comparison" compare={true}>
```javascript !! js
// JavaScript: Explicit exports
// file: utils.js
export const publicVariable = "I'm public";
export function publicFunction() {
    return "I'm public";
}

const privateVariable = "I'm private";
function privateFunction() {
    return "I'm private";
}

// Default export
export default function mainFunction() {
    return "I'm the default export";
}

// file: main.js
import mainFunction, { publicVariable, publicFunction } from './utils.js';
```

```go !! go
// Go: Capitalization-based visibility
// file: utils/utils.go
package utils

// Exported (capitalized)
var PublicVariable = "I'm public"
func PublicFunction() string {
    return "I'm public"
}

// Unexported (lowercase)
var privateVariable = "I'm private"
func privateFunction() string {
    return "I'm private"
}

// file: main.go
package main

import (
    "fmt"
    "./utils"
)

func main() {
    fmt.Println(utils.PublicVariable)    // ✅ Accessible
    fmt.Println(utils.PublicFunction())  // ✅ Accessible
    // fmt.Println(utils.privateVariable) // ❌ Not accessible
    // fmt.Println(utils.privateFunction()) // ❌ Not accessible
}
```
</UniversalEditor>

## Go Modules and Dependency Management

Go modules provide a modern approach to dependency management with versioning and reproducible builds.

### Module Files

<UniversalEditor title="Module Files Comparison" compare={true}>
```javascript !! js
// JavaScript: package.json and package-lock.json
// package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18.2",
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "jest": "^29.5.0"
  },
  "scripts": {
    "start": "node index.js",
    "test": "jest"
  }
}

// package-lock.json (auto-generated)
// Contains exact versions and dependency tree
```

```go !! go
// Go: go.mod and go.sum
// go.mod
module my-app

go 1.21

require (
    github.com/gin-gonic/gin v1.9.1
    github.com/go-sql-driver/mysql v1.7.1
)

require (
    github.com/bytedance/sonic v1.9.1 // indirect
    github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
    // ... more indirect dependencies
)

// go.sum (auto-generated)
// Contains cryptographic hashes for reproducible builds
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
// ... more hashes
```
</UniversalEditor>

### Dependency Management Commands

<UniversalEditor title="Dependency Management Commands" compare={true}>
```javascript !! js
// JavaScript: npm/yarn commands
// Install dependencies
npm install
yarn install

// Add new dependency
npm install express
yarn add express

// Add development dependency
npm install --save-dev jest
yarn add --dev jest

// Remove dependency
npm uninstall lodash
yarn remove lodash

// Update dependencies
npm update
yarn upgrade

// List dependencies
npm list
yarn list
```

```go !! go
// Go: go mod commands
// Initialize module
go mod init my-project

// Add dependencies
go get github.com/gin-gonic/gin
go get github.com/go-sql-driver/mysql@v1.7.1

// Remove unused dependencies
go mod tidy

// Download dependencies
go mod download

// Verify dependencies
go mod verify

// List dependencies
go list -m all

// Update dependencies
go get -u github.com/gin-gonic/gin
go get -u all
```
</UniversalEditor>

### Go Module Path Format Deep Dive

The `github.com/xxxx` format in Go is not just a naming convention, but the core of the entire dependency management system:

<UniversalEditor title="Module Path Format Deep Dive" compare={true}>
```javascript !! js
// JavaScript: Package name separated from repository
// package.json
{
  "name": "my-awesome-lib",        // Package name can be arbitrary
  "repository": {                  // Repository info configured separately
    "type": "git",
    "url": "https://github.com/user/my-awesome-lib.git"
  },
  "dependencies": {
    "express": "^4.18.2"          // Package name, no repository info
  }
}

// Package name and repository can be completely different
// Package name: "lodash"
// Repository: https://github.com/lodash/lodash.git

// Import using only package name
import express from 'express';
import _ from 'lodash';
```

```go !! go
// Go: Module path directly corresponds to repository
// go.mod
module github.com/user/my-project  // Module path must correspond to repository

require (
    github.com/gin-gonic/gin v1.9.1    // Path = repository address
    github.com/go-sql-driver/mysql v1.7.1
)

// Module path format rules:
// 1. Must correspond to actual Git repository address
// 2. Format: {host}/{owner}/{repo}
// 3. Common formats:
//    - github.com/user/repo
//    - gitlab.com/user/repo
//    - bitbucket.org/user/repo
//    - golang.org/x/text (official extensions)
//    - google.golang.org/grpc (Google official)

// Import using complete path
import (
    "github.com/gin-gonic/gin"     // Path must match repository
    "github.com/go-sql-driver/mysql"
)
```
</UniversalEditor>

### Module Path Advantages and Challenges

<UniversalEditor title="Module Path Advantages and Challenges" compare={true}>
```javascript !! js
// JavaScript: Package name system characteristics
// Advantages:
// 1. Package names are concise and easy to remember
// 2. Package names can be independent of repository
// 3. Support for scoped packages (@org/package)
// 4. Can rename packages
// 5. Good private package support

// Challenges:
// 1. Package names may not match repository names
// 2. Requires additional repository configuration
// 3. Package name conflicts
// 4. Dependency sources not transparent enough

// Example: Package name separated from repository
{
  "name": "awesome-utils",           // Package name
  "repository": "git://github.com/user/old-repo-name.git"  // Repository
}

// Users only see package name when using
import utils from 'awesome-utils';  // Don't know actual repository
```

```go !! go
// Go: Module path system characteristics
// Advantages:
// 1. Path directly corresponds to repository, high transparency
// 2. Avoid package name conflicts
// 3. Automatic handling of repository migrations
// 4. Support for multiple Git hosting services
// 5. Version control integrated with Git tags

// Challenges:
// 1. Paths are long and not concise
// 2. Dependency on repository availability
// 3. Complex private repository configuration
// 4. Network dependency issues

// Example: Path directly corresponds to repository
require (
    github.com/gin-gonic/gin v1.9.1  // Directly corresponds to https://github.com/gin-gonic/gin
)

// Users see complete path when using
import "github.com/gin-gonic/gin"    // Clearly know repository location
```
</UniversalEditor>

## Package Types and Conventions

Go has several types of packages with specific purposes and conventions.

### Main Package

The `main` package is special in Go - it's the entry point for executable programs.

<UniversalEditor title="Main Package Example" compare={true}>
```javascript !! js
// JavaScript: Entry point
// file: index.js
const express = require('express');
const app = express();

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.listen(3000, () => {
    console.log('Server running on port 3000');
});

// package.json
{
  "scripts": {
    "start": "node index.js"
  }
}
```

```go !! go
// Go: Main package
// file: main.go
package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello World!")
    })
    
    fmt.Println("Server running on port 3000")
    http.ListenAndServe(":3000", nil)
}

// Build and run
// go build
// ./my-app
```
</UniversalEditor>

### Library Packages

Library packages are reusable code that can be imported by other packages.

<UniversalEditor title="Library Package Example" compare={true}>
```javascript !! js
// JavaScript: Library module
// file: math-utils.js
export class Calculator {
    static add(a, b) {
        return a + b;
    }
    
    static multiply(a, b) {
        return a * b;
    }
}

export const PI = 3.14159;
export const E = 2.71828;

// file: main.js
import { Calculator, PI } from './math-utils.js';
console.log(Calculator.add(5, 3));
console.log(PI);
```

```go !! go
// Go: Library package
// file: math/calculator.go
package math

const PI = 3.14159
const E = 2.71828

type Calculator struct{}

func (c *Calculator) Add(a, b float64) float64 {
    return a + b
}

func (c *Calculator) Multiply(a, b float64) float64 {
    return a * b
}

// Static methods (package-level functions)
func Add(a, b float64) float64 {
    return a + b
}

func Multiply(a, b float64) float64 {
    return a * b
}

// file: main.go
package main

import (
    "fmt"
    "./math"
)

func main() {
    calc := &math.Calculator{}
    fmt.Println(calc.Add(5, 3))
    fmt.Println(math.Add(5, 3)) // Static function
    fmt.Println(math.PI)
}
```
</UniversalEditor>

## Internal Packages

Go has a special `internal` directory for packages that should only be used within the current module.

<UniversalEditor title="Internal Packages Example" compare={true}>
```javascript !! js
// JavaScript: No built-in internal concept
// Convention: Use underscore prefix or place in private directory
// file: _internal/helpers.js
export function internalHelper() {
    return "internal";
}

// file: main.js
import { internalHelper } from './_internal/helpers.js';
// Note: This is just a convention, not enforced by the language
```

```go !! go
// Go: Internal packages (enforced by compiler)
// file: internal/helpers/helpers.go
package helpers

func InternalHelper() string {
    return "internal"
}

// file: main.go
package main

import (
    "fmt"
    "./internal/helpers" // ✅ Can import from internal
)

func main() {
    fmt.Println(helpers.InternalHelper())
}

// file: another-module/main.go
package main

import (
    "fmt"
    "github.com/user/my-project/internal/helpers" // ❌ Cannot import from another module's internal
)

func main() {
    // This will cause a compilation error
    fmt.Println(helpers.InternalHelper())
}
```
</UniversalEditor>

## Vendor Directory and Dependency Management

Go supports vendoring dependencies for offline development and reproducible builds.

<UniversalEditor title="Vendor Directory Example" compare={true}>
```javascript !! js
// JavaScript: No built-in vendoring
// Convention: Use npm pack or copy node_modules
// npm pack creates a tarball with dependencies
// npm pack express

// Or manually copy dependencies
// cp -r node_modules vendor/
```

```go !! go
// Go: Vendor directory
// Create vendor directory with dependencies
go mod vendor

// This creates:
my-project/
├── go.mod
├── go.sum
├── vendor/
│   ├── github.com/
│   │   └── gin-gonic/
│   │       └── gin/
│   │           ├── go.mod
│   │           └── *.go
│   └── modules.txt
└── main.go

// Build with vendored dependencies
go build -mod=vendor

// Or set environment variable
export GOFLAGS="-mod=vendor"
go build
```
</UniversalEditor>

## Workspace Support (Go 1.18+)

Go workspaces allow managing multiple modules in a single workspace, similar to JavaScript monorepos.

<UniversalEditor title="Workspace Example" compare={true}>
```javascript !! js
// JavaScript: Monorepo with workspaces
// package.json (root)
{
  "name": "my-monorepo",
  "workspaces": [
    "packages/*"
  ],
  "private": true
}

// packages/app/package.json
{
  "name": "@my-org/app",
  "dependencies": {
    "@my-org/utils": "workspace:*"
  }
}

// packages/utils/package.json
{
  "name": "@my-org/utils",
  "version": "1.0.0"
}
```

```go !! go
// Go: Workspaces (Go 1.18+)
// go.work (root)
go 1.21

use (
    ./app
    ./utils
    ./shared
)

// app/go.mod
module my-org/app

go 1.21

require my-org/utils v0.0.0

replace my-org/utils => ../utils

// utils/go.mod
module my-org/utils

go 1.21

// shared/go.mod
module my-org/shared

go 1.21

// Initialize workspace
go work init ./app ./utils ./shared

// Add modules to workspace
go work use ./new-module

// Remove modules from workspace
go work edit -dropuse ./old-module
```
</UniversalEditor>

---

### Real Project Comparison Example

Let's compare the two package management approaches through a real web application project:

<UniversalEditor title="Real Project Comparison" compare={true}>
```javascript !! js
// JavaScript: Express.js Web Application
// package.json
{
  "name": "my-web-app",
  "version": "1.0.0",
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.5.0",
    "bcryptjs": "^2.4.3",
    "jsonwebtoken": "^9.0.2",
    "cors": "^2.8.5"
  },
  "devDependencies": {
    "nodemon": "^3.0.1",
    "jest": "^29.5.0"
  }
}

// Install dependencies
npm install

// Project structure
my-web-app/
├── package.json
├── node_modules/          # All dependencies here
├── src/
│   ├── routes/
│   ├── models/
│   └── middleware/
└── tests/

// Import dependencies
import express from 'express';
import mongoose from 'mongoose';
import bcrypt from 'bcryptjs';
```

```go !! go
// Go: Gin Web Application
// go.mod
module github.com/user/my-web-app

go 1.21

require (
    github.com/gin-gonic/gin v1.9.1
    go.mongodb.org/mongo-driver v1.12.1
    golang.org/x/crypto v0.14.0
    github.com/golang-jwt/jwt/v5 v5.0.0
    github.com/gin-contrib/cors v1.4.0
)

// Install dependencies
go mod tidy

// Project structure
my-web-app/
├── go.mod
├── go.sum
├── cmd/
│   └── main.go
├── internal/
│   ├── handlers/
│   ├── models/
│   └── middleware/
└── tests/

// Import dependencies
import (
    "github.com/gin-gonic/gin"
    "go.mongodb.org/mongo-driver/mongo"
    "golang.org/x/crypto/bcrypt"
    "github.com/golang-jwt/jwt/v5"
)
```
</UniversalEditor>

### Key Differences Summary

| Feature | JavaScript (npm) | Go (go mod) |
|---------|------------------|-------------|
| **Package Identifier** | Simple package name (`express`) | Complete repository path (`github.com/gin-gonic/gin`) |
| **Dependency Source** | npm registry | Git repositories |
| **Version Control** | Semantic versioning + package-lock.json | Git tags + go.sum |
| **Private Packages** | Scoped packages (`@company/pkg`) | Private Git repositories (`git.company.com/pkg`) |
| **Cache Location** | `node_modules/` | `$GOPATH/pkg/mod/` |
| **Dependency Resolution** | Registry-based queries | Git repository cloning |
| **Network Dependency** | Depends on npm registry availability | Depends on Git repository availability |
| **Transparency** | Package name separated from repository | Path directly corresponds to repository |

### Practice Questions:
1. Explain the difference between Go's package system and JavaScript's module system. What are the advantages and disadvantages of each approach?
2. What is the significance of the `internal` directory in Go, and how does it differ from JavaScript's approach to private modules?
3. How does Go's capitalization-based visibility system work, and how does it compare to JavaScript's explicit export/import system?
4. Create a Go module with multiple packages and demonstrate how to organize code using the standard Go project layout.

### Project Idea:
* Build a simple web application using Go modules. Create separate packages for handlers, models, and utilities. Use the standard Go project layout and demonstrate proper package organization, dependency management, and module structure.

### Next Steps:
* Learn about Go's type system and interfaces
* Explore Go's powerful concurrency features with goroutines and channels
* Understand Go's error handling patterns and best practices
